package com.muddog.TaxiWell;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Iterator;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;

import com.google.android.maps.GeoPoint;


public class TaxiHelperActivity extends Activity implements OnClickListener {
	
	private static final int ERR_NO_SADDR = R.string.err_no_srcaddr;
	private static final int ERR_NO_DADDR = R.string.err_no_dstaddr;

	
	class LocationSelector implements OnClickListener {
		
		private static final int MODE_ADDR = 0;
		private static final int MODE_MYLOC = 1;
		private static final int MODE_ONMAP = 2;
		private static final int REQ_GETONMAP = 0;

		public EditText mEditor;	// the edit text view
		public View mButton;	// the button view
		private int mMode = MODE_ADDR;  // location mode
		private String mAddress;	// user inputed address
		private String mTitle;	// dialog title
		
		public LocationSelector(View editor, View button) {
			mEditor = (EditText)editor;
	        mButton = button;
	        mButton.setOnClickListener(this);
		}
		
		public void setDialogTitle(String title) {
			mTitle = title;
		}
		
		/**
		 * set mode:
		 * 1. user input address
		 * 2. my location (GPS or GSM)
		 * 3. select on map
		 * @param mode
		 */
		private void setMode(int mode) {
			switch (mode) {
			case MODE_ADDR:
				mEditor.setEnabled(true);
				mEditor.setText(mAddress);
				break;
			case MODE_MYLOC:
				mEditor.setEnabled(false);
				mEditor.setText(R.string.editext_myloc);
				break;
			case MODE_ONMAP:
				mEditor.setEnabled(false);
				mEditor.setText(R.string.editext_onmap);
				break;
			default:
				return;
			}
			mMode = mode;
		}

		/**
		 * save the current user input
		 */
		public void save() {
			if (mMode == MODE_ADDR) {
				mAddress = mEditor.getText().toString().trim();
			}
		}
		
		public String getAddress() {
			return mAddress;
		}

		@Override
		public void onClick(View v) {
			
			// open alert dialog for selection
			AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
			builder.setTitle(mTitle);
			builder.setSingleChoiceItems(R.array.select_location, -1,
					new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								setMode(which);
							}
					});
			
			// create and show the dialog
			AlertDialog alert = builder.create();
			alert.show();
			
			// process the select on map
			if (mMode == MODE_ONMAP) {
				Intent intent = new Intent(getApplicationContext(), ShowMapActivity.class);
				intent.putExtra("getpoint", true);
				startActivityForResult(intent, REQ_GETONMAP);
			}
		}
		
		/*
		 * Receive the activity result
		 */
		protected void onActivityResult(int requestCode, int resultCode, Intent data) {
			if (requestCode == REQ_GETONMAP) {
				
			}
		}
			
	};

	private LocationSelector mSrcLocSel;
	private LocationSelector mDstLocSel;
	private List<Integer> mErrList;
		
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        View btnResult = this.findViewById(R.id.btn_result);
        btnResult.setOnClickListener(this);
        View btnMap = this.findViewById(R.id.btn_map);
        btnMap.setOnClickListener(this);

        mSrcLocSel = new LocationSelector(
        					this.findViewById(R.id.edit_start_location), 
        					this.findViewById(R.id.btn_start));
        mDstLocSel = new LocationSelector(
        					this.findViewById(R.id.edit_end_location),
        					this.findViewById(R.id.btn_end));
        
        Resources res = this.getResources();
        mSrcLocSel.setDialogTitle(res.getString(R.string.select_start_title));
        mDstLocSel.setDialogTitle(res.getString(R.string.select_end_title));
	}

	@Override
	public void onClick(View v) {
		
		switch (v.getId()) {

		case R.id.btn_result:
			if (false == getDistanceAndFee()) {
				// show alert with error string
				break;
			}
			break;
		case R.id.btn_map:
			break;
		
		}
	}

	/**
	 * Get the user input Geo point in the text editor.
	 * If it's my current position, and got from map, we directly get double points.
	 * If it's input address string, we do Geocoder to get point.
	 * @param gp
	 * @return
	 */
	private boolean getInputGeoPoint(GeoPoint src_gp, GeoPoint dst_gp) {
		
		Resources res = this.getResources();
		// check the start/end editor firstly
		String src_loc = mSrcLocSel.getText().toString().trim();
		String dst_loc = mDstLocSel.getText().toString().trim();
		
		// get the current location or specified on Map
		if (!mSrcLocEdit.isEnabled()) {
			if (src_loc == res.getString(R.string.mode_myloc)) {
				
			} else if (src_loc == res.getString(R.string.mode_onmap)) {
				
			}
		} else {
			
		}
		if (!mDstLocEdit.isEnabled()) {
			
		} else {
			
		}
		
		if (0 == src_loc.length() || 0 == dst_loc.length()) {
			// 
			return false;
		}
		
		Geocoder geoCoder = new Geocoder(this, Locale.getDefault());    
		try {
			List<Address> addresses = 
						geoCoder.getFromLocationName(src_loc, 5); // TODO: make 5 configurable
			if (addresses.isEmpty()) {
				// we have no such start address
				putError(ERR_NO_SADDR);
				return false;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Button call back.
	 * get the distance and taxi fee, and shows on textview
	 * @return
	 */
	private boolean getDistanceAndFee() {
		
		GeoPoint srcPoint, dstPoint;
		
		if (!getInputGeoPoint(srcPoint, dstPoint)) {
			// if error, show it.
			return false;
		}
		

		
		// send navigation request
		// need refine? do refine
		// get distance
		// calculate the fee
		// fill the text view with result
		return true;
	}

	/**
	 * Append the error resource id into mErrList.
	 * @param errid
	 */
	private void putError(int errid) {
		mErrList.add(new Integer(errid));
	}
	
	/**
	 * Get error strings' list
	 * @return list of string
	 */
	private List<String> getErrors() {
		
		Resources res = this.getResources();
		List<String> retList = new ArrayList<String>();
		Iterator<Integer> it = mErrList.iterator();
		
		while (it.hasNext()) {
			 retList.add(res.getString(it.next().intValue()));
		}
		
		return retList;
	}

	/**
	 * open the location selector menu list
	 * @param selector
	 */
	private void openLocationSelector(final String selector) {
		


	}
	/**
	 * Let user to tap the point on Google Map
	 * @return GeoPoint of the point on map
	 */
	private GeoPoint getPointOnMap() {
		
	}
	
	/**
	 * get geo point by user input address
	 * @param address
	 * @return GeoPoint of the address
	 */
	private GeoPoint getPointByAddress(String address) {
		
	}
	
	/**
	 * get geo point by GPS or GSM
	 * @return
	 */
	private GeoPoint getPointByGPS() {
		
	}
}
